const parseHtmlToAst = require("../benHtmlParst")
const benLog = require("../benLog")
const csstree = require('css-tree');

class htmlPlugin {
	constructor(components) {
		this.components = components
		this.useComponents = {}
	}
	getCode() {
		let z = "abcdefghijklmnopqrstuvwxyz1234657890",
			str = []
		for (let i = 0; i < 8; i++) {
			str.push(z[parseInt(Math.random() * z.length)])
		}
		return str.join("")
	}
	apply(compiler) {

		compiler.hooks.done.tap('htmlPlugin', (stats) => {
			// 在构建完成后执行操作
		});
		compiler.hooks.emit.tap('htmPuglin', (compilation) => {
			// 读取名称为 fileName 的输出资源
			const asset = compilation.assets;
			for (let file of Object.keys(asset).filter(f => /.html$/.test(f))) {
				let htmlDom = parseHtmlToAst(asset[file].source())
				let bodyDom = htmlDom.children[1]
				console.log(htmlDom)
				this.replaceDom(bodyDom.children)
				let htmlStr = this.astToHtml(htmlDom)
				htmlStr += "<style>"
				Object.keys(this.useComponents).forEach((comId) => {
					let tag = this.useComponents[comId]
					let styleAst = this.deepCopy(this.components[tag].style)
					this.astToStyle(styleAst, comId)
					htmlStr += csstree.generate(styleAst, {
						mode: 'safe'
					})
				})
				htmlStr += "</style>"
				compilation.assets[file] = {
					source: () => htmlStr,
					size: () => htmlStr.length
				}
			}
		});

	}
	replaceDom(domParent) {

		for (let dom of Object.keys(domParent)) {
			if (domParent[dom].type != 1) continue
			if (domParent[dom].children && domParent[dom].children.length) {
				this.replaceDom(domParent[dom].children)
			}
			if (/[A-Z][a-z]{1,}/.test(domParent[dom].tag)) {
				try {
					let comTag = domParent[dom].tag
					let comId = this.getCode()
					domParent[dom] = this.deepCopy(this.components[domParent[dom].tag].template);
					domParent[dom].attrs.push({
						name: "comId",
						value: comId
					});
					this.useComponents[comId] = comTag
					benLog.notice(comTag + "组件加载完成")
				} catch (e) {
					benLog.error(domParent[dom].tag + "组件加载异常", e)
					// benLog.log()
				}
			}
		}

	}
	astToHtml = (domTree) => {
		if (domTree.type == 3) {
			return domTree.text
		}
		let attrs = domTree.attrs
		let openTag =
			`<${domTree.tag}${attrs && attrs.length ? (" " + attrs.map((attr) => `${attr.name}${attr.value ? '="' + attr.value + '"' : ""}`).join(" ")) : ""}>`
		if (domTree.children) {
			openTag += domTree.children.map((d) => {
				return this.astToHtml(d)
			}).join("")
		}
		console.log(domTree)
		openTag += `</${domTree.tag}>`
		return openTag
	}
	astToStyle(ast, comId) {
		ast.children.forEach((line) => {
			line.prelude.children.forEach((selector) => {
				selector.children.unshift({
					"type": "AttributeSelector",
					"loc": null,
					"name": {
						"type": "Identifier",
						"loc": null,
						"name": "comId"
					},
					"matcher": "=",
					"value": {
						"type": "String",
						"loc": null,
						"value": "" + comId
					},
					"flags": null
				}, {
					"type": "Combinator",
					"loc": null,
					"name": " "
				})
			})
		})
	}
	deepCopy(obj) {
		return JSON.parse(JSON.stringify(obj));
	}
}
module.exports = htmlPlugin;